#region Copyright
// 
// Copyright (C) 2008 VirtualStaticVoid <virtualstaticvoid@gmail.com>
// 
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
#endregion

using System;
using System.Diagnostics;
using System.Linq;
using NUnit.Framework;

namespace NAom.DAL
{

  [TestFixture]
  public class EntityTypeTests
  {

    [SetUp]
    public void Setup()
    {
      
    }

  //  [Test]
    public void LoadEntityTypesAndAttributes()
    {

      AomDBDataContext dbCtx = new AomDBDataContext();

      EntityType entityTypeCountry = new EntityType("Country");
      entityTypeCountry.AttributeTypes.Add(new EntityAttributeType("Description", AttributeDataType.String));

      EntityType entityTypeIssuer = new EntityType("Issuer");
      entityTypeIssuer.AttributeTypes.Add(new EntityAttributeType("Description", AttributeDataType.String));
      entityTypeIssuer.AttributeTypes.Add(new EntityAttributeType("Country", entityTypeCountry));

      EntityType entityTypeInstrument = new EntityType("Instrument");
      entityTypeInstrument.AttributeTypes.Add(new EntityAttributeType("Description", AttributeDataType.String));
      entityTypeInstrument.AttributeTypes.Add(new EntityAttributeType("Issuer", entityTypeIssuer));
      entityTypeInstrument.AttributeTypes.Add(new EntityAttributeType("Country", entityTypeCountry));
      entityTypeInstrument.AttributeTypes.Add(new EntityAttributeType("MarketCapitalization", AttributeDataType.Decimal));

      dbCtx.EntityTypes.InsertAllOnSubmit(new[]
                                            {
                                              entityTypeCountry,
                                              entityTypeIssuer,
                                              entityTypeInstrument
                                            });

      dbCtx.SubmitChanges();

      dbCtx.GenerateEntityTypeObjects();
      
    }

  //  [Test]
    public void LoadEntityTypesAndAttributes2()
    {

      AomDBDataContext dbCtx = new AomDBDataContext();

      EntityType entityTypeCountry = new EntityType("Country");
      entityTypeCountry.AttributeTypes.Add(new EntityAttributeType("Description", AttributeDataType.String));

      EntityType entityTypeIssuer = new EntityType("Issuer");
      entityTypeIssuer.AttributeTypes.Add(new EntityAttributeType("Description", AttributeDataType.String));
      entityTypeIssuer.AttributeTypes.Add(new EntityAttributeType("Country", entityTypeCountry));

      EntityType entityTypeInstrument = new EntityType("Instrument");
      entityTypeInstrument.AttributeTypes.Add(new EntityAttributeType("Description", AttributeDataType.String));
      entityTypeInstrument.AttributeTypes.Add(new EntityAttributeType("Issuer", entityTypeIssuer));
      entityTypeInstrument.AttributeTypes.Add(new EntityAttributeType("Country", entityTypeCountry));

      EntityAttributeType marketCapitalization = new EntityAttributeType("MarketCapitalization",
                                                                         AttributeDataType.Decimal);
      
      entityTypeInstrument.AttributeTypes.Add(marketCapitalization);

      dbCtx.EntityTypes.InsertAllOnSubmit(new[]
                                            {
                                              entityTypeCountry,
                                              entityTypeIssuer,
                                              entityTypeInstrument
                                            });

      dbCtx.SubmitChanges();

      dbCtx.GenerateEntityTypeObjects();

      EntityRepository<IEntity> instrumentRepository = entityTypeInstrument.CreateEntityRepository<IEntity>();

      var entitiesList =
        from e in instrumentRepository.GetAll()
        select e;

      Assert.AreEqual(entitiesList.ToList().Count, 0);

      foreach (var entity in entitiesList)
      {
        Debug.WriteLine(entity.ToString());
      }

      const int ITEM_LOAD_COUNT = 100;
      for (int i = 0; i < ITEM_LOAD_COUNT; i++)
      {
        IEntity entity = instrumentRepository.CreateInstance();
        entity.Name = String.Format("Item{0:00000}", i + 1);
        entity.SetProperty(marketCapitalization, (decimal?)(i % 1999m));
        instrumentRepository.Add(entity);
      }

      Assert.AreEqual(entitiesList.ToList().Count, ITEM_LOAD_COUNT);

      foreach (var entity in entitiesList)
      {
        Console.WriteLine("{0}, {1}, \"{2}\"", entity.Id, entity.Version, entity.Name);
      }

    }

  //  [Test]
    public void RetrieveEntityTypesAndAttributes()
    {

      AomDBDataContext dbCtx = new AomDBDataContext();

      var entityTypes =
        from et in dbCtx.EntityTypes
        select et;

      foreach(EntityType entityType in entityTypes)
      {
        Console.WriteLine(entityType.Name);
        foreach(EntityAttributeType attributeType in entityType.AttributeTypes)
        {
          Console.WriteLine(" >> " + attributeType.Name);
        }
      }

    }

    [Test]
    public void WorkInProgress()
    {

      #region Load Entities & Attributes Meta

      AomDBDataContext dbCtx = new AomDBDataContext();

      EntityType entityTypeCountry = new EntityType("Country");
      entityTypeCountry.AttributeTypes.Add(new EntityAttributeType("Description", AttributeDataType.String));

      EntityType entityTypeIssuer = new EntityType("Issuer");
      entityTypeIssuer.AttributeTypes.Add(new EntityAttributeType("Description", AttributeDataType.String));
      entityTypeIssuer.AttributeTypes.Add(new EntityAttributeType("Country", entityTypeCountry));

      EntityType entityTypeInstrument = new EntityType("Instrument");
      entityTypeInstrument.AttributeTypes.Add(new EntityAttributeType("Description", AttributeDataType.String));
      entityTypeInstrument.AttributeTypes.Add(new EntityAttributeType("Issuer", entityTypeIssuer));
      entityTypeInstrument.AttributeTypes.Add(new EntityAttributeType("Country", entityTypeCountry));

      EntityAttributeType marketCapitalization = new EntityAttributeType("MarketCapitalization", AttributeDataType.Decimal);
      EntityAttributeType listedIndicator = new EntityAttributeType("ListedIndicator", AttributeDataType.Boolean);

      entityTypeInstrument.AttributeTypes.Add(marketCapitalization);
      entityTypeInstrument.AttributeTypes.Add(listedIndicator);

      dbCtx.EntityTypes.InsertAllOnSubmit(new[]
                                            {
                                              entityTypeCountry,
                                              entityTypeIssuer,
                                              entityTypeInstrument
                                            });

      dbCtx.SubmitChanges();

      dbCtx.GenerateEntityTypeObjects();

      #endregion

      #region Load Entities

      EntityRepository<IEntity> instrumentRepository = entityTypeInstrument.CreateEntityRepository<IEntity>();

      const int ITEM_LOAD_COUNT = 100;
      for (int i = 0; i < ITEM_LOAD_COUNT; i++)
      {
        IEntity entity = instrumentRepository.CreateInstance();
        entity.Name = String.Format("Item{0:00000}", i + 1);
        entity.SetProperty(marketCapitalization, (decimal?)(i % 1999m));
        entity.SetProperty(listedIndicator, true);
        instrumentRepository.Add(entity);
      }

      #endregion

      var instrumentList1 =
        from e in instrumentRepository.GetAll()
        where e.GetProperty<IEntity, decimal?>(marketCapitalization) > 0  && 
              e.GetProperty<IEntity, bool?>(listedIndicator) == true
        select e;

      foreach (var entity in instrumentList1)
      {
        Console.WriteLine("{0}, {1}, \"{2}\"", entity.Id, entity.Version, entity.Name);
      }

    }

  }

}
